﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports Microsoft.Samples.WindowsPhoneCloud.Web.UserAccountWrappers
Imports Microsoft.Samples.WindowsPhoneCloud.Web.Models
Imports Microsoft.Samples.WindowsPhoneCloud.Web.Infrastructure
Imports System.Security.Principal
Imports System.Globalization

Namespace Controllers
    <HandleError()>
    Public Class AccountController
        Inherits System.Web.Mvc.Controller

        Private ReadOnly userPrivilegesRepository As IUserPrivilegesRepository

        Public Sub New()
            Me.New(New UserTablesServiceContext())
        End Sub

        <CLSCompliant(False)>
        Public Sub New(ByVal userPrivilegesRepository As IUserPrivilegesRepository)
            Me.userPrivilegesRepository = userPrivilegesRepository
        End Sub

        Public Function Unauthorized() As ActionResult
            Return Me.View()
        End Function

        Public Function LogOn() As ActionResult
            Return Me.View(New LogOnModel())
        End Function

        <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", Justification:="Needs to take same parameter type as Controller.Redirect()"), HttpPost(), ValidateAntiForgeryToken()> _
        Public Function LogOn(ByVal model As LogOnModel, ByVal returnUrl As String) As ActionResult
            If ModelState.IsValid Then
                If Membership.ValidateUser(model.UserName, model.Password) Then
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe)
                    If Url.IsLocalUrl(returnUrl) AndAlso returnUrl.Length > 1 AndAlso returnUrl.StartsWith("/") _
                       AndAlso Not returnUrl.StartsWith("//") AndAlso Not returnUrl.StartsWith("/\\") Then
                        Return Redirect(returnUrl)
                    Else
                        Return RedirectToAction("Index", "Home")
                    End If
                Else
                    ModelState.AddModelError("", "The user name or password provided is incorrect.")
                End If
            End If

            ' If we got this far, something failed, redisplay form
            Return View(model)
        End Function

        Public Function LogOff() As ActionResult
            FormsAuthentication.SignOut()

            Return RedirectToAction("Index", "Home")
        End Function

#If MEMBERSHIP Then
        Public Function Register() As ActionResult
            Return View()
        End Function

        <HttpPost(), ValidateAntiForgeryToken()> _
        Public Function Register(ByVal model As RegisterModel) As ActionResult
            If ModelState.IsValid Then
                ' Attempt to register the user
                Dim createStatus As MembershipCreateStatus
                Membership.CreateUser(model.UserName, model.Password, model.Email, Nothing, Nothing, True, Nothing, createStatus)

                If createStatus = MembershipCreateStatus.Success Then
                    FormsAuthentication.SetAuthCookie(model.UserName, False) ' createPersistentCookie
                    Me.SetUserDefaultUserPrivileges(Membership.GetUser(model.UserName).ProviderUserKey.ToString())
                    Return RedirectToAction("Index", "Home")
                Else
                    ModelState.AddModelError(String.Empty, ErrorCodeToString(createStatus))
                End If
            End If

            ' If we got this far, something failed, redisplay form
            Return View(model)
        End Function

        Private Shared Function ErrorCodeToString(ByVal createStatus As MembershipCreateStatus) As String
            ' See http://go.microsoft.com/fwlink/?LinkID=177550 for
            ' a full list of status codes.
            Select Case createStatus
                Case MembershipCreateStatus.DuplicateUserName
                    Return "User name already exists. Please enter a different user name."

                Case MembershipCreateStatus.DuplicateEmail
                    Return "A user name for that e-mail address already exists. Please enter a different e-mail address."

                Case MembershipCreateStatus.InvalidPassword
                    Return "The password provided is invalid. Please enter a valid password value."

                Case MembershipCreateStatus.InvalidEmail
                    Return "The e-mail address provided is invalid. Please check the value and try again."

                Case MembershipCreateStatus.InvalidAnswer
                    Return "The password retrieval answer provided is invalid. Please check the value and try again."

                Case MembershipCreateStatus.InvalidQuestion
                    Return "The password retrieval question provided is invalid. Please check the value and try again."

                Case MembershipCreateStatus.InvalidUserName
                    Return "The user name provided is invalid. Please check the value and try again."

                Case MembershipCreateStatus.ProviderError
                    Return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator."

                Case MembershipCreateStatus.UserRejected
                    Return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator."

                Case Else
                    Return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator."
            End Select
        End Function

        Private Sub SetUserDefaultUserPrivileges(ByVal userId As String)
            Me.userPrivilegesRepository.AddPrivilegeToUser(userId, PrivilegeConstants.TablesUsagePrivilege)
            Me.userPrivilegesRepository.AddPrivilegeToUser(userId, PrivilegeConstants.BlobsUsagePrivilege)
            Me.userPrivilegesRepository.AddPrivilegeToUser(userId, PrivilegeConstants.QueuesUsagePrivilege)
            Me.userPrivilegesRepository.AddPrivilegeToUser(userId, PrivilegeConstants.SqlUsagePrivilege)
            Me.userPrivilegesRepository.AddPrivilegeToUser(userId, String.Format(CultureInfo.InvariantCulture, "{0}{1}", "SampleData", PrivilegeConstants.TablePrivilegeSuffix))
        End Sub
#End If
    End Class
End Namespace